//
//  Push.swift
//  JKTool
//
//  Created by 姜奎 on 2022/6/23.
//

import Foundation
extension JKTool.Git {
    struct Push: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "push",
            _superCommandName: "git",
            abstract: "push")
        
        @Option(name: .shortAndLong, help: "push branch name")
        var branch: String?
        
        @Option(name: .shortAndLong, help: "递归子模块，default：false")
        var recursive: Bool = false
        
        @Option(name: .shortAndLong, help: "remote-name，default：origin")
        var upstream: String?
        
        @Option(name: .shortAndLong, help: "遇到错误时终止，default：false")
        var exitError: Bool = false
        
        @Option(name: .shortAndLong, help: "执行路径")
        var path: String?
        
        mutating func run() {
            
            guard let project = Project.project(directoryPath: path ?? FileManager.default.currentDirectoryPath) else {
                return po(tip: "\(path ?? FileManager.default.currentDirectoryPath)目录没有检索到工程", type: .error)
            }
            
            guard project.rootProject == project, recursive == true  else {
                push(project: project)
               return
            }
            
            po(tip: "======Push工程开始======", type: .tip)

            let pool = ThreadPool()

            for record in project.recordList {
                pool.addTask(priority: 1, handle: {[self] in
                    guard let pro = Project.project(directoryPath: "\(project.checkoutsPath)/\(record)") else {
                        po(tip: "\(record) 工程不存在，请检查 Modulefile.recordList 是否为最新内容",type: .exitError(exitError))
                        return
                    }
                    self.push(project: pro)
                })
            }

            pool.addTask(priority: 0) {[self] in
                self.push(project: project)
            }

            pool.start()
            
            po(tip: "======Push工程完成======")
        }

        func push(project: Project){

            guard let currentBranch = branch ?? (try? shellOut(to: .gitCurrentBranch(), at: project.directoryPath)) else {
                return po(tip: "【\(project.directoryEntrance)】 Push失败\n" + "无法检索出当前分支名",type: .error)
            }

            do {
                try shellOut(to: .gitPush(upStream: upstream,branch: currentBranch), at: project.directoryPath)
                po(tip: "【\(project.directoryEntrance)】Push[\(currentBranch)]完成", type: .tip)
            } catch {
                let error = error as! ShellOutError
                po(tip: "【\(project.directoryEntrance)】 Push[\(currentBranch)]失败\n" + error.message + error.output,type: .exitError(exitError))
            }
        }
    }
}
